#include "pch.h"
#include "MathFoundation.h"
namespace mini
{
	CVector3D crossProduct(const CVector3D& a, const CVector3D& b)
	{
		return CVector3D(
			a.y * b.z - a.z * b.y,
			a.z * b.x - a.x * b.z,
			a.x* b.y - a.y * b.x);
	}

	CVector3D operator*(float fvalue, const CVector3D& v)
	{
		return CVector3D(fvalue * v.x, fvalue * v.y, fvalue * v.z);
	}

	void CalculateTangentBinormal(VertexFormatVTNTB& vertex0,
		VertexFormatVTNTB& vertex1,
		VertexFormatVTNTB& vertex2,
		CPoint3F& tangent, CPoint3F& binormal)
	{
		float vector1[3], vector2[3];
		float tuVector[2], tvVector[2];

		// Calculate the two vectors for this face.
		vector1[0] = vertex1.position.x - vertex0.position.x;
		vector1[1] = vertex1.position.y - vertex0.position.y;
		vector1[2] = vertex1.position.z - vertex0.position.z;

		vector2[0] = vertex2.position.x - vertex0.position.x;
		vector2[1] = vertex2.position.y - vertex0.position.y;
		vector2[2] = vertex2.position.z - vertex0.position.z;

		// Calculate the tu and tv texture space vectors.
		tuVector[0] = vertex1.uv.x - vertex0.uv.x;
		tvVector[0] = vertex1.uv.y - vertex0.uv.y;

		tuVector[1] = vertex2.uv.x - vertex0.uv.x;
		tvVector[1] = vertex2.uv.y - vertex0.uv.y;

		// Calculate the denominator of the tangent/binormal equation.
		float den = 1.0f / (tuVector[0] * tvVector[1] - tuVector[1] * tvVector[0]);

		// Calculate the cross products and multiply by the coefficient to get the tangent and binormal.
		tangent.x = (tvVector[1] * vector1[0] - tvVector[0] * vector2[0]) * den;
		tangent.y = (tvVector[1] * vector1[1] - tvVector[0] * vector2[1]) * den;
		tangent.z = (tvVector[1] * vector1[2] - tvVector[0] * vector2[2]) * den;

		binormal.x = (tuVector[0] * vector2[0] - tuVector[1] * vector1[0]) * den;
		binormal.y = (tuVector[0] * vector2[1] - tuVector[1] * vector1[1]) * den;
		binormal.z = (tuVector[0] * vector2[2] - tuVector[1] * vector1[2]) * den;

		// Calculate the length of this normal.
		float length = 1 /( sqrt((tangent.x * tangent.x) + (tangent.y * tangent.y) + (tangent.z * tangent.z)) + 0.00000001f);

		// Normalize the normal and then store it
		tangent.x = tangent.x * length;
		tangent.y = tangent.y * length;
		tangent.z = tangent.z * length;

		// Calculate the length of this normal.
		length = 1 / (sqrt((binormal.x * binormal.x) + (binormal.y * binormal.y) + (binormal.z * binormal.z)) + 0.00000001f );

		// Normalize the normal and then store it
		binormal.x = binormal.x * length;
		binormal.y = binormal.y * length;
		binormal.z = binormal.z * length;
	}

	void CalculateNormal(CPoint3F& tangent, CPoint3F& binormal, CPoint3F& normal)
	{
		// Calculate the cross product of the tangent and binormal which will give the normal vector.
		normal.x = (tangent.y * binormal.z) - (tangent.z * binormal.y);
		normal.y = (tangent.z * binormal.x) - (tangent.x * binormal.z);
		normal.z = (tangent.x * binormal.y) - (tangent.y * binormal.x);

		// Calculate the length of the normal.
		float length = 1 / (sqrt((normal.x * normal.x) + (normal.y * normal.y) + (normal.z * normal.z)) + 0.00000001f );
		// Normalize the normal.
		normal.x = normal.x * length;
		normal.y = normal.y * length;
		normal.z = normal.z * length;
	}

	void MatrixTo(CMatrix* pInOut, const CPoint3F& pt)
	{
		pInOut->m[3][0] = pt.x;
		pInOut->m[3][1] = pt.y;
		pInOut->m[3][2] = pt.z;
	}
}
